
package cn.benma666.kettle.mytuils;

import cn.benma666.dict.Zdlb;
import cn.benma666.iframe.DictManager;
import cn.benma666.kettle.domain.KettleKzZykz;
import cn.benma666.kettle.domain.RJobentry;
import cn.benma666.kettle.domain.RJobentryAttribute;
import cn.benma666.kettle.domain.VJob;
import cn.benma666.kettle.vo.ZyglDssz;
import cn.benma666.myutils.ClassUtil;
import cn.benma666.myutils.StringUtil;
import cn.benma666.sjzt.Db;
import cn.benma666.sjzt.MyLambdaQuery;
import com.alibaba.fastjson.util.TypeUtils;
import org.beetl.sql.core.query.LambdaQuery;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.job.entries.special.JobEntrySpecial;

import java.util.List;

/**
* 任务定时 <br/>
* date: 2016年5月24日 <br/>
* @author jingma
* @version 0.1
*/
public class TimingUtil{

	/**
	* 将定时对象转为简单可理解的文本 <br/>
	* @author jingma
	* @param timing 定时对象
	*/
	public static String showText(ZyglDssz timing){
        //定时类别
        int schedulerType = Integer.parseInt(timing.getSchedulerType());
        int hour = timing.getHour();
        int minutes = timing.getMinutes();
        String result = "";
        if(JobEntrySpecial.NOSCHEDULING==schedulerType){
            result = "不需要定时";
        }else if(JobEntrySpecial.INTERVAL==schedulerType){
            int intervalSeconds = timing.getIntervalSeconds();
            int intervalMinutes = timing.getIntervalMinutes();
            if(intervalMinutes==0){
                result = "等"+intervalSeconds+"秒";
            }else{
                result = "等"+intervalMinutes+"分"+intervalSeconds+"秒";
            }
        }else if(JobEntrySpecial.DAILY==schedulerType){
            result = "一天的"+hour+"点"+minutes+"分";
        }else if(JobEntrySpecial.WEEKLY==schedulerType){
            String week = DictManager.zdMcByDm(Zdlb.SYS_COMMON_XQ.name(),timing.getWeekDay());
            result = week + "的"+hour+"点"+minutes+"分";
        }else if(JobEntrySpecial.MONTHLY==schedulerType){
            int dayOfMonth = timing.getDayOfMonth();
            result = "一个月的"+dayOfMonth+"日"+hour+"点"+minutes+"分";
        }else if(JobEntrySpecial.CRON==schedulerType){
            result = timing.getCron();
        }
        if(TypeUtils.castToBoolean(timing.getRepeat())){
            result+="/重";
        }
        if(TypeUtils.castToBoolean(timing.getInitStart())){
            result+="/初";
        }
        return result;
	}
	/**
	* 根据作业id得到定时配置的字符串描述 <br/>
	* @author jingma
	*/
	public static String showTextByJobid(VJob job) {
	    return showText(getTimingByJobId(job));
	}

    /**
    * 通过作业ID获取作业定时信息<br/>
    * @author jingma
    * @param job 作业
    * @return SATRT控件实体
    */
    public static ZyglDssz getTimingByJobId(VJob job) {
        Integer startId = getStartIdByJobId(job);
        final MyLambdaQuery<RJobentryAttribute> jobentryAttributeMyLambdaQuery = Db.use(job.getZyk())
                .lambdaQuery(RJobentryAttribute.class);
        final List<RJobentryAttribute> jobentryAttributeList = jobentryAttributeMyLambdaQuery
                .andEq(RJobentryAttribute::getIdJobentry, startId).select();
        ZyglDssz result = new ZyglDssz();
        for(RJobentryAttribute record:jobentryAttributeList){
            if(StringUtil.isNotBlank(record.getValueStr())){
                ClassUtil.setVal(record.getCode(), record.getValueStr(), result);
            }else{
                ClassUtil.setVal(record.getCode(), record.getValueNum().intValue(), result);
            }
        }
        if(StringUtil.isBlank(result.getCron())){
            //设置个默认值
            result.setCron("0 0 * * * ? *");
        }
        result.setRepeat(StringUtil.whether(result.getRepeat())+"");
        result.setInitStart(StringUtil.whether(result.getInitStart())+"");
        return result;
    }

    /**
    * 根据作业id获取该作业的开始控件id <br/>
    * @author jingma
    */
    public static Integer getStartIdByJobId(VJob job) {
        //START控件的类型编号是74，每个JOB只有一个START控件，所有可以唯一确定
        final MyLambdaQuery<RJobentry> jobentryMyLambdaQuery = Db.use(job.getZyk()).lambdaQuery(RJobentry.class);
        RJobentry startIdObj = jobentryMyLambdaQuery.andEq(RJobentry::getIdJob, job.getIdJob())
                .andEq(RJobentry::getIdJobentryType, KettleManager.getJobentryTypeId(job,"SPECIAL")).singleSimple();
        return StringUtil.requireNonNull(startIdObj,"没有找到作业的开始控件").getIdJobentry();
    }
    /**
    * 保存定时到kettle的表中方式 <br/>
    * 直接修改相关表数据，效率高，存在风险<br/>
    * @author jingma
    */
    public static void saveTimingToKettle(VJob job, ZyglDssz timing) throws KettleException {
        Integer startId = getStartIdByJobId(job);
        final LambdaQuery<RJobentryAttribute> jaLambdaQuery = Db
                .useSqlManager(job.getZyk()).lambdaQuery(RJobentryAttribute.class);
        for(String key:new String[]{"repeat","initStart"}){
            Object val = ClassUtil.getVal(key, null, timing);
            if(StringUtil.isNotBlank(val)){
                jaLambdaQuery.andEq(RJobentryAttribute::getIdJobentry, startId)
                        .andEq(RJobentryAttribute::getCode, key)
                        .updateSelective(RJobentryAttribute.builder().valueStr(
                                TypeUtils.castToBoolean(val)?"Y":"N").build());
            }
        }
        for(String key:new String[]{"schedulerType","intervalSeconds","intervalMinutes",
                "hour","minutes","weekDay","dayOfMonth"}){
            Object val = ClassUtil.getVal(key, null, timing);
            if(StringUtil.isNotBlank(val)){
                jaLambdaQuery.andEq(RJobentryAttribute::getIdJobentry, startId)
                        .andEq(RJobentryAttribute::getCode, key)
                        .updateSelective(RJobentryAttribute.builder().valueNum(
                                Double.parseDouble(val+"")).build());
            }
        }
        if(StringUtil.isNotBlank(timing.getCron())){
            jaLambdaQuery.andEq(RJobentryAttribute::getIdJobentry, startId)
                    .andEq(RJobentryAttribute::getCode, "cron")
                    .updateSelective(RJobentryAttribute.builder().valueStr(
                            timing.getCron()).build());
        }
        KettleManager.updateZykz(KettleKzZykz.builder().zyk(job.getZyk())
                .idJob(job.getIdJob()).dsms(showText(getTimingByJobId(job))).build());
    }
}
